<?php
/**
 * Created by PhpStorm.
 * User: Vito
 * Date: 2022/6/20
 * Time: 14:42
 */

namespace app\api\controller\v1;

use app\api\controller\BaseController;
use app\common\ErrorCode;
use app\common\EventName;
use app\common\Util;
use app\exception\MessageException;
use app\logic\AgentLogic;
use app\logic\SystemConfigLogic;
use app\logic\UserLogic;
use app\logic\UserOauthLogic;
use app\model\UserOauth;
use app\service\RedisStoreService;
use app\service\TokenService;
use app\service\WechatService;
use app\validate\WechatOauthValidate;
use EasyWeChat\Kernel\Messages\Message;
use EasyWeChat\Kernel\Messages\News;
use EasyWeChat\Kernel\Messages\NewsItem;
use Overtrue\Socialite\Exceptions\AuthorizeFailedException;
use think\facade\Db;
use think\facade\Event;
use think\facade\Log;
use think\helper\Str;
use app\model\TestLog;
use app\service\Wechat\WechatH5Service;
use app\model\Timing;
class Wechat extends BaseController
{
    const NOT_NEED_LOGIN = ['api'];

    protected $methodName = [
        'index'             => '微信接口',
        'login'             => '授权登录',
        'callback'          => '授权登录回调',
        'test'              => '测试获取token',
        'getQRcode'         => '获取临时二维码',
        'sendWorthMessage'  => '发送催缴模板消息',
        'sendAuditMessage'  => '发送审核模板消息',
        'timing'            => '测试定时任务'
    ];

    /**
     * @var WechatService
     */
    protected $wechat;

    protected $message = [];

    protected $openid;
    protected $toUser;

    public function index()
    {
        $this->wechat = $wechat = new WechatService();

        $this->message = $wechat->server->getMessage();
        $this->openid  = $this->message['FromUserName'] ?? '';
        $this->toUser  = $this->message['ToUserName'] ?? '';
        $wechat->server->push([$this, 'event'], Message::EVENT);

        $response = $wechat->server->serve();
        $response->send();

        if (is_dev()) {
            die;
        }

        return '';
    }

    public function callback($code = '', $state = '')
    {
        WechatOauthValidate::batchCheck(['code' => $code], 'code');
        try {
            $cache = new RedisStoreService();
            
            if ($cache->has($code)) {
                $attribute = $cache->get($code);
                $user      = new \Overtrue\Socialite\User(unserialize($attribute));
            } else {
                $this->wechat = $wechat = new WechatService();
                $user         = $wechat->oauth->userFromCode($code);
                $attribute    = $user->serialize();
                // 缓存授权信息
                $cache->set($code, $attribute, is_dev() ? 86400 : 60);
            }
            TestLog::addTestLog($user);
            $id         = $user->getId();
            $nickname   = $user->getNickname();
            $avatar     = $user->getAvatar();
            $oauthLogic = new UserOauthLogic();

            if($state == 6){
                $TYPE_WECHAT = $state;
                $userType    = TokenService::REPAIR;
            }else{
                $TYPE_WECHAT = UserOauth::TYPE_WECHAT;
                $userType    = TokenService::USER;
            }
            
            $oauth = $oauthLogic->getModel()->where('openid', $id)->where('type', $TYPE_WECHAT)->find();
            if (!$oauth) {
                Db::startTrans();
                try {
                    $userinfo = $this->register($nickname, $avatar, $TYPE_WECHAT);
                    $oauth = $oauthLogic->getModel()->add([
                        'openid'   => $id,
                        'nickname' => $nickname,
                        'avatar'   => $avatar,
                        'user_id'  => $userinfo->id,
                        'type'     => $TYPE_WECHAT,
                    ]);

                    if ($oauth) {
                        Db::commit();
                    } else {
                        Db::rollback();
                        throw new MessageException('授权登录失败');
                    }

                } catch (\Exception $e) {
                    Db::rollback();

                    Log::write("微信授权登录失败：" . $e->getMessage());

                    throw new MessageException('授权登录失败');
                }

            } else {
                
                if ($state == 6) {
                    $userinfo = $oauth->repairUser;
                } else {
                    $userinfo = $oauth->user;
                }
                if (!$userinfo) {
                    $userinfo       = $this->register($nickname, $avatar);
                    $oauth->user_id = $userinfo->id;
                    $oauth->save();
                }
            }
            
            Event::trigger(EventName::USER_LOGIN, ['user' => $userinfo, 'type' => $userType]);
            return $this->success($userinfo);

        } catch (AuthorizeFailedException $e) {
            return $this->error(ErrorCode::PARAM_ERROR, '错误的授权码');
        }
    }

    public function login($type = 'userinfo')
    {

        $params = $this->request->post();


        WechatOauthValidate::batchCheck(['scope' => $type], 'scope');

        $this->wechat = $wechat = new WechatService();
        
        if($params['type_id'] == 6){
            $callback = web('client_host').'?type_id='. $params['type_id'].'#/'. 'pages/Mstaff/Mstaff';
        }else{
            $callback = web('client_host');
        }
        

        $redirectUrl = $wechat->oauth->scopes(['snsapi_' . $type])
            ->redirect($callback);
            // ->redirect();
        return $this->success(['url' => $redirectUrl]);
    }

    /**
     * 事件
     * @param $message
     */
    public function event($message)
    {
        TestLog::addTestLog($message);
        $event    = $message['Event'];
        $eventKey = $message['EventKey'] ? $message['EventKey'] : $message['Event'];

        if (in_array($event, ['subscribe', 'SCAN'])) {
            //扫码注册维护员二维码
            if (preg_match("/repair_register_(\d*?)$/", $eventKey, $matches)) {
                [, $agentID] = $matches;

                return $this->repairRegister($agentID);
            }
        }

    }

    /**
     * 响应运营商注册维护员链接(已废弃)
     * @param $agentID
     * @return News|string
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     */
    // protected function repairRegister($agentID)
    // {
    //     $logic = new AgentLogic();
    //     $agent = $logic->getByID($agentID);
    //     if (!$agent) {
    //         return '找不到相关运营商';
    //     }

    //     if ($agent->isDisabled()) {
    //         return '运营商已下线';
    //     }

    //     $items = [
    //         new NewsItem([
    //             'title'       => '注册成为维护员',
    //             'description' => '点击进入注册',
    //             'url'         => web('repair_host') . web('repair_register_uri') . '?' . http_build_query(['agent_id' => $agentID]),
    //             'image'       => Util::link(SystemConfigLogic::get('wechat_share_img')),
    //         ]),
    //     ];

    //     return new News($items);
    // }

    protected function register($nickname, $avatar = '',$type = 1)
    {
        $userLogic = new UserLogic();
//        $nickname  = trim_emoji($nickname);
        if (!$nickname) {
            $nickname = '微信授权';
        }
        if($type == 6){
            $userinfo = $userLogic->register([
                'username' => 'repair_' . Str::random(10),
                'nickname' => $nickname . Str::random(5),
                'password' => 'a123456.',
                'avatar'   => $avatar,
                'money'    => 0,
                'flow'     => 0,
                'add_ip'   => $this->request->ip(),
                'platform' => \app\model\User::WX_PLATFORM,
                'status'   => 0
            ], $type);
        }else{
            $userinfo = $userLogic->register([
                'username' => 'oauth_' . Str::random(10),
                'nickname' => $nickname . Str::random(5),
                'password' => 'a123456.',
                'avatar'   => $avatar,
                'money'    => 0,
                'flow'     => 0,
                'add_ip'   => $this->request->ip(),
                'platform' => \app\model\User::WX_PLATFORM,
            ]);
        }
        

        return $userinfo;
    }

    /**
     * @Description: 测试获取access_token
     * @author: xiayu <cb1071403016@126.com>
     * @Date: 2022-11-24 10:43:30
     * @version: 1.0.0
     * @return [type]
     */    
    public function test(){
        $WechatH5 = new WechatH5Service;

        $token = $WechatH5->getAccessToken();
        print_r($token);
    }

    /**
     * @Description: 获取临时二维码
     * @author: xiayu <cb1071403016@126.com>
     * @Date: 2022-11-24 16:32:35
     * @version: 1.0.0
     * @return [type]
     */    
    public function getQRcode(){
        $WechatH5 = new WechatH5Service;

        $url = $WechatH5->getQRcode();
        // print_r($token);
        return $this->success(['url'=> $url],'获取成功');
    }
    /**
     * @Description: 发送催缴通知
     * @author: xiayu <cb1071403016@126.com>
     * @Date: 2022-11-24 17:23:42
     * @version: 1.0.0
     * @return [type]
     */
    public function sendWorthMessage(){
        $WechatH5 = new WechatH5Service;

        $res= $WechatH5->sendWorthMessage();
        // print_r($token);
        return $this->success($res, '发送成功');
    }
    /**
     * @Description: 发送审核通知
     * @author: xiayu <cb1071403016@126.com>
     * @Date: 2022-11-24 17:23:42
     * @version: 1.0.0
     * @return [type]
     */
    public function sendAuditMessage(){
        $WechatH5 = new WechatH5Service;
        // $res = Timing::getTim();
        $res = $WechatH5->sendAuditMessage();
        // print_r($token);
        
        return $this->success($res, '发送成功');
    }

    /**
     * @Description: 测试定时任务
     * @author: xiayu <cb1071403016@126.com>
     * @Date: 2022-11-27 11:24:11
     * @version: 1.0.0
     * @return [type]
     */    
    public function timing(){

       $res = Event::trigger(EventName::CRONTAB_TASK);
       return $this->success($res,'获取成功');
    }
}
